package Day_0201.JUC;

/**
 * @author zxc
 * @date 2023/02/01 21:38
 **/
public class ThreadLocal {
    public static void main(String[] args) {
        /**
         * ThreadLocal的原理
         * ===》
         * 1.ThreadLocal可以理解为线程本地变量，
         * 它会在每个线程都创建一个副本，那么在线程之间访问内部副本变量就行了，做到了线程之间互相隔离，
         * 相比于synchronized的做法是用空间来换时间。
         * ===》
         * 即，由于Java中对象的创建基本上都在堆上，ThreadLocal可以理解为线程本地变量;
         * (即，某线程创建的对象是专属于该线程的，其存储在ThreadLocal中;)
         * 注意 ：该线程所创建的对象，若是使用ThreadLocal来存储该对象的话，则线程之间相互隔离;
         *
         * 2.ThreadLocal有一个静态内部类ThreadLocalMap，ThreadLocalMap又包含了一个Entry数组，
         * Entry本身是一个弱引用，key是指向ThreadLocal的弱引用，Entry具备了保存key-value键值对的能力。
         * ===>
         * 即，ThreadLocalMap是与每一个Thread相对应的;
         * （即，每一个Thread都拥有专属于其的TheadLocalMap;）
         * 同时，ThreadLocalMap是用来存储Entry值（键值对的映射关系;）;
         * ThreadLocalMap中，key为指向ThreadLocal的弱引用;同时，value为所要存储的真实数据;
         *
         * 内存泄漏问题 ：
         * （1）弱引用的目的是为了防止内存泄露，
         * （2）如果是强引用那么ThreadLocal对象除非线程结束否则始终无法被回收，弱引用则会在下一次GC的时候被回收。
         * （3）但是这样还是会存在内存泄露的问题，
         *  假如key和ThreadLocal对象被回收之后，entry中就存在key为null，
         *  但是value有值的entry对象，但是永远没办法被访问到，同样除非线程结束运行。
         *  但是只要ThreadLocal使用恰当，在使用完之后调用remove方法删除Entry对象，实际上是不会出现这个问题的。
         */
    }
}
